#include "cli_handler.h"
#include "cli_network.h"
#include "cli_auth.h"
#include "thread.h"
#include "color.h"
#include "beautify.h"

void handleCommand(UserInfo_t *user, int socket_fd, int tunnel_fd)
{
    char cmd_line[512] = {0};
    strcpy(cmd_line, "/");
    int len = sizeof(cmd_line);

    bool is_login = false;
    CAT_MSG("欢迎来到一个简单的喵喵云盘~ 请先登录或注册喵!");
    CAT_MSG("输入login登录, 输入signup注册, 输入quit退出~");

    while (1)
    {
        char line[512] = {0};
        sprintf(line, "%s%s:%s%s%.*s%s %s$%s ",
                COLOR_GREEN_BOLD, user->name, COLOR_RESET,
                COLOR_CYAN_BOLD, len, cmd_line, COLOR_RESET,
                COLOR_YELLOW_BOLD, COLOR_RESET);
        printf("%s", line);

        char input[512];
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = '\0'; // 移除换行符

        Command_t command = parseCommand(input);
        if (!isValidCommand(command.type))
        {
            PRINT_INFO("Invalid command.");
            continue;
        }

        if (command.type == CMD_QUIT)
        {
            printf("Executing quit command.\n"); // 直接返回
            return;
        }

        if (command.type == CMD_HELP)
        {
            handleHelpCommand(command.arg1); // 处理 help 指令
            continue;
        }

        if (!is_login && command.type == CMD_LOGIN)
        {
            CAT_MSG("喵~ 请输入你的用户名和密码，开始使用吧！");
            if (login(&command, user, socket_fd) == 0)
            {
                is_login = true;
            }
            continue;
        }
        else if (!is_login && command.type == CMD_SIGNUP)
        {
            CAT_MSG("喵喵~ 还不是我们的用户吗？快来注册一个吧！");
            signUp(&command, user, socket_fd);
            continue;
        }

        if (!is_login)
        {
            CAT_MSG("喵~ 请先登录再进行操作哦 (๑•̀ㅂ•́)و✧");
            continue;
        }

        // 确定登录后再发送命令
        sendAll(socket_fd, &command, sizeof(Command_t), 0); // 先发送命令结构体
        if (command.type == CMD_DOWNLOAD)
        {
            command.client_fd = tunnel_fd;
            // downloadFile(tunnel_fd, command.arg1, command.arg2);
            createThread(downloadFile, &command);
        }
        else if (command.type == CMD_UPLOAD)
        {
            command.client_fd = tunnel_fd;
            // uploadFile(tunnel_fd, command.arg1, command.arg2);
            createThread(uploadFile, &command);
        }
        else
        {
            Response_t resp;
            memset(&resp, 0, sizeof(Response_t));

            if (recvAll(socket_fd, &resp, sizeof(resp) - sizeof(char *), 0) == 0)
            {
                PRINT_INFO("Server closed connection");
                break;
            }
            // 接收可变大小的 resp 部分
            if (resp.resp_len > 0)
            {
                resp.resp = (char *)malloc(resp.resp_len + 1);
                if (resp.resp == NULL)
                {
                    PRINT_ERROR("failed to malloc resp.resp");
                    continue;
                }

                if (recvAll(socket_fd, resp.resp, resp.resp_len, 0) == 0)
                {
                    PRINT_ERROR("Server closed connection while receiving response");
                    free(resp.resp);
                    break;
                }
                resp.resp[resp.resp_len] = '\0'; // 确保字符串以 '\0' 结尾
            }
            else
            {
                resp.resp = NULL;
            }

            if (!resp.if_success)
            {
                PRINT_INFO("Command execution failed!");
                if (resp.resp != NULL)
                {
                    puts(resp.resp);
                    free(resp.resp);
                }
                continue;
            }
            switch (command.type)
            {
            case CMD_LS:
                if (resp.resp != NULL)
                {
                    printf("%s", resp.resp);
                }
                break;
            case CMD_LL:
                if (resp.resp != NULL)
                {
                    printf("%s", resp.resp);
                }
                break;
            case CMD_CD:
                strcpy(cmd_line, resp.pwd);
                break;
            case CMD_PWD:
                puts(resp.pwd);
                break;
            case CMD_REMOVE:
            case CMD_MV:
            case CMD_MKDIR:
                if (resp.resp != NULL)
                {
                    puts(resp.resp);
                }
            default:
                break;
            }

            // 释放 resp 内存
            if (resp.resp != NULL)
            {
                free(resp.resp);
            }
        }
    }
}
